Skip to content

Comments

Feature: Mobile UI improvements, file naming templates, and bug fixes#1

Merged
Quickkill0 merged 47 commits intomainfrom
fixes
Feb 18, 2026
Merged

Feature: Mobile UI improvements, file naming templates, and bug fixes#1
Quickkill0 merged 47 commits intomainfrom
fixes

Conversation

@Quickkill0
Copy link
Owner

Summary

  • Mobile & responsive UI: Improved mobile layouts across library, source cards, provider page, import wizard, and setup wizard; added series details modal for mobile on the Newly Minted page and fixed tablet/foldable screen layouts
  • File naming & output formats: Added configurable file naming templates with a template parser, output format options (CBZ/PDF), and a dedicated naming settings section with live preview and rename support
  • Bug fixes & stability: Resolved critical race conditions, RSC payload 404 errors breaking manga search, thumbnail 400 errors, cover image loading issues, import stuck states, SignalR connection errors, and incorrect queue status enum usage
  • Infrastructure & tooling: Added Docker build workflow, Unraid template with GPU passthrough support, switched frontend build to pnpm, added a comprehensive test suite covering archive writing, job queue concurrency, template parsing, and async locking

Kaizoku Code Quality Bot added 30 commits February 17, 2026 16:01
- Fix non-atomic thread slot checking in JobQueueHostedService using lock + ConcurrentDictionary
- Fix non-thread-safe HashSet mutation by replacing with ConcurrentDictionary<string, byte>
- Fix unsafe semaphore disposal in KeyedAsyncLock with reference counting
- Fix mixed sync/async locking in DownloadCommandService with proper SemaphoreSlim
- Add infinite loop prevention in JobScheduledHostedService with iteration guards
- Add reflection caching in JobExecutionService for O(1) command lookup
- Add input validation to controllers to prevent path traversal attacks
- Add PathValidationHelper utility for path and GUID validation
- Add test project with 18 unit tests for concurrency fixes
- Add cancellation token check and Task.Yield() in KeyedAsyncLock retry loop to prevent CPU exhaustion
- Remove overly restrictive ~ character from path validation (valid on many systems)
- Rename _lock to _seriesLock in DownloadCommandService for clarity
- Builds Docker image for specified branch
- Supports linux/amd64 and linux/arm64 platforms
- Pushes to ghcr.io with branch-based or custom tag
- Builds frontend (Next.js) and backend (.NET 9) in CI
- Uses GitHub Actions cache for faster builds
- Add kaizoku.xml.example template for Unraid Community Applications
- Configure ports 9833 (Web UI) and 4567 (Suwayomi)
- Set up volume mappings for config and downloads
- Include PUID/PGID environment variables for permissions
- Gitignore local template customizations (*.xml)
package-lock.json is out of sync with package.json (major version upgrades
to React 19, Next.js 15, Tailwind 4, etc). Using npm install to regenerate
the lock file during build.
- Project enforces pnpm via preinstall script
- Update workflow to use pnpm/action-setup@v4
- Use pnpm install --frozen-lockfile for reproducible builds
- Regenerate pnpm-lock.yaml with current dependencies
Implements user-configurable naming templates for downloaded files and folders:
- Template variables: {Series}, {Chapter}, {Volume}, {Provider}, {Scanlator},
  {Language}, {Title}, {Year}, {Month}, {Day}
- Support for padding formats like {Chapter:000}
- Output format selection: CBZ (default) or PDF
- Global settings with backward-compatible defaults

Backend changes:
- New template parser system (Services/Naming/)
- New archive writer abstraction supporting CBZ and PDF (Services/Archives/)
- Settings properties for templates, padding, and output format
- Validation and preview API endpoints
- Updated DownloadCommandService to use templates

Frontend changes:
- New "Naming & Format" settings section with live preview
- Clickable variable chips for easy template editing
- Output format, padding, and chapter title options

Tests:
- 50+ TemplateParser tests covering parsing, validation, edge cases
- 30+ ArchiveWriter tests for CBZ/PDF creation and factory
Adds NVIDIA GPU support for JCEF/CEF rendering:
- Added --gpus all to ExtraParams
- Added NVIDIA_VISIBLE_DEVICES and NVIDIA_DRIVER_CAPABILITIES env vars
- Fix decimal chapter padding (5.5 with format 000 now correctly yields 005.5)
- Use settings.ChapterPadding and settings.VolumePadding when no format specified
- Add CancellationToken check in CbzArchiveWriter.WriteEntryAsync
- Fix missing space in FormatVolume return statement
Root causes:
1. SignalR startConnection() called when not in Disconnected state
2. Empty imports showed "Loading Series" forever instead of actionable message
3. Wizard state persisted in localStorage but backend state cleared on restart

Fixes:
- progressHub.ts: Only call start() when state is Disconnected, wait for
  Connecting/Reconnecting states to complete instead of throwing error
- confirm-imports-step.tsx: Show "No series found" message with "Start Over"
  button when imports are empty, instead of misleading "Loading Series"
- import-wizard-provider.tsx: Add lastUpdated timestamp to state and clear
  stale states older than 24 hours on load
Dialog changes:
- Responsive padding (p-4 on mobile, p-6 on desktop)
- Max height with overflow-y-auto for scrolling
- Touch-friendly close button (44px tap target)

Footer navigation changes:
- Stack buttons vertically on mobile, horizontal on desktop
- Full-width buttons on mobile for easier tapping
- Step indicator reordered for mobile layout
- Touch-friendly button heights (min-h-44px)

Confirm imports step changes:
- Tabs scroll horizontally on mobile instead of overflowing
- Shortened tab labels on mobile (e.g., "Imported" vs "Already Imported")
- Responsive content heights (40vh mobile, 59vh desktop)
- Import cards stack vertically on mobile
- Smaller thumbnails on mobile
- Responsive input widths
- Touch-friendly controls throughout

All changes use Tailwind responsive breakpoints (sm:, md:, lg:)
- Dialog: Add overflow-x-hidden to prevent horizontal scroll
- Dialog: Use w-[95vw] on mobile for consistent width
- Dialog: Reduce padding to p-3 on mobile
- Wizard modals: Use responsive width (98vw mobile, 95vw tablet, 90% desktop)
- Wizard modals: Add overflow-hidden and min-w-0 to content containers
- Preferences step: Reduce max-height on mobile (50vh vs 60vh)
- Preferences step: Add overflow-x-hidden to scrollable container

Fixes content running over modal edges on mobile screens.
Users couldn't easily find their tracked manga - the only way to access
/library was by clicking the app logo, which wasn't obvious. Added an
explicit Library sidebar link using the already-imported Library icon.
- Replace all "Kaizoku.NET" text references with "Kaizoku" in:
  - Frontend UI strings (page titles, descriptions, wizard messages)
  - Backend metadata (API title, ComicInfo notes)
  - Tray app (window titles, tooltips)
  - README and build scripts

- Create new minimalist book icon (kaizoku-logo.png) replacing
  the old Luffy image (kaizoku.net.png)

- Rename image assets:
  - kaizoku.net.png -> kaizoku-logo.png
  - kaizoku.net.ico -> kaizoku-logo.ico

- Update all image references throughout codebase to use new filenames
- Update GitHub URLs from Kaizoku.NET to Kaizoku
- Update Docker image references from kaizoku.net to kaizoku
- Update unraid template with new repo and container URLs
- Add overflow-hidden and min-w-0 to card containers to prevent horizontal scroll
- Make action buttons flow naturally on mobile, absolute positioned on desktop
- Add truncate class to titles and provider names for text overflow
- Make genre badges wrap with flex-wrap instead of overflowing
- Stack author/artist grid to single column on mobile
- Stack switch controls to single column on mobile
- Make series header card flex-col on mobile, flex-row on desktop
- Center poster image on mobile with reduced height
- Add break-words to description and metadata text
- Add responsive width classes throughout
Change sampleData parameter type from Record<string, string> to
typeof SAMPLE_DATA to ensure proper type inference for property access.
The zip command was including the 'out/' prefix in all paths,
causing files to extract to wwwroot/out/ instead of wwwroot/.
Changed to zip from within the out/ directory to avoid the prefix.
- Remove separate chapter/volume padding dropdown options
- Padding is now specified inline in templates: {Chapter:000}, {Volume:00}
- Add "Rename Existing Files" button to apply current naming scheme
- Add /api/settings/rename-files endpoint
- Update TemplateParser to only use format from template string
- Simplify frontend UI with cleaner variable chips including padding examples
- Add ITemplateParser and ILogger to SettingsService
- Implement RenameFilesToCurrentSchemeAsync with full functionality:
  - Iterates through all series, providers, and chapters
  - Builds current file path from storage folder + series path + filename
  - Creates TemplateVariables from chapter metadata
  - Generates new filename using current template settings
  - Preserves original file extension
  - Renames file and updates database
  - Handles errors gracefully with logging
  - Skips files that don't exist or would cause overwrites
Regenerate book icon PNG with proper alpha transparency.
Light/checkered background pixels are now fully transparent
so the icon displays correctly on dark backgrounds.
- Remove automatic file renaming from ArchiveHelperService to avoid
  conflicts between MakeFileNameSafe and template-based naming
- Update SeriesProviderService to use ITemplateParser for consistent
  filename generation when matching chapters
- Fix logging bug in RenameFilesToCurrentSchemeAsync (logged wrong filename)
- Regenerate book logo with proper transparent background using SVG
- Add DELETE /api/downloads/clear endpoint
- Add ClearAllDownloadsAsync method to JobManagementService
- Clears all waiting/queued download jobs from the queue
Kaizoku Code Quality Bot and others added 17 commits February 17, 2026 16:02
1. Remove invalid ThenInclude(sp => sp.Chapters) from rename operation
   - Chapters is stored as JSON in SeriesProvider, not a navigation property
   - EF Core throws InvalidOperationException when using ThenInclude on it
   - Chapters are loaded automatically with SeriesProvider rows

2. Handle empty ThumbnailUrl in ToSeriesInfo/ToSeriesExtendedInfo
   - When ThumbnailUrl is empty, BaseUrl was returned alone (invalid URL)
   - Now falls back to "serie/thumb/unknown" for a valid placeholder image
1. Add null check to LatestSerie.ToSeriesInfo ThumbnailUrl (ModelExtensions.cs)
   - When thumbnailUrl is null/empty, now falls back to "serie/thumb/unknown"
   - Prevents returning invalid URLs like just the base URL

2. Make RewriteToKaizokuPath robust (FileSystemExtensions.cs)
   - Add validation for URLs that don't contain "/manga/"
   - Add validation for URLs without trailing slash after manga ID
   - Return fallback "serie/thumb/unknown" instead of crashing

3. Replace placeholder icon with smaller, cleaner version
   - New minimal book outline design with blue Kaizoku branding
   - Reduced from 12KB to 1.4KB
   - Clean spine and page lines, transparent background
The GetSeriesThumbAsync endpoint was validating the ID as a GUID,
but thumbnail IDs are in format "{suwayomiId}!{timestamp}" (e.g., "522!1770219118")
or "unknown", not GUIDs.

Changed validation to just check for non-empty string - the service
handles parsing and validation of the thumbnail ID format safely.
Next.js 15 with trailingSlash: true generates RSC payloads at
/{route}/index.txt but the client requests them at /{route}.txt.
This path mismatch caused 404s that broke navigation and search.

Added middleware to rewrite RSC requests to the correct path.
- Changed layout to stack cover image above content on mobile
- Made thumbnail smaller on mobile (h-48 vs h-68) with max-width
- Centered thumbnail and text content on mobile
- Centered badges, tags, and provider info on mobile
- Hide "Settings" text on mobile, show only gear icon
- Hide "Remove/Uninstall" text on mobile, show only trash icon
- Hide "Install" text on mobile, show only download icon
- Hide "Install From APK" text on mobile, show only upload icon
- Made filter selects smaller on mobile (w-28 vs w-40)
- Added flex-wrap to filter row so it wraps on narrow screens
- Reduced height of select triggers on mobile (h-8 vs h-10)
- Reduced text size on mobile (text-xs vs text-sm)
- Reduced padding and gaps on mobile
- Made sidebar toggle button larger for better touch targets (36px min)
- Reduced header height on mobile
- Changed action buttons from sm:absolute to lg:absolute (1024px)
- Changed chapter input from sm:absolute to lg:absolute
- Changed thumbnail/content layout from sm: to md: breakpoint (768px)
- Made button text icon-only on mobile (hidden sm:inline)
- Prevents controls from overlapping on intermediate screens like Z Fold
Add ability for users to remove individual scheduled downloads from the queue.
- Changed image/content layout from sm:flex-row to md:flex-row (768px)
- Changed status badge from sm:absolute to lg:absolute (1024px)
- Changed action buttons from sm:absolute to lg:absolute
- Shortened button text on mobile (Delete Series → Delete, etc.)
- Centered buttons on mobile/tablet, right-aligned on desktop
- Consistent breakpoint strategy with source cards
Mobile users couldn't access series details or add manga since the
hover tooltip doesn't work on touch devices. This adds a click-triggered
modal that shows the same series information and provides action buttons
to view the source or add the series to the library.
- Add concurrency locking (SemaphoreSlim) to prevent concurrent import operations
- Wrap SaveImportsAsync in a database transaction for atomicity
- Remove AsNoTracking() from ImportSeriesAsync to prevent lost writes
- Add warning logs when chapters are removed during scan
- Fix silently skipped jobs to report actual "skipped" status
- Mark failed search imports as Skip instead of leaving them stuck
- Guard against division by zero in FillMissingChapterNumbers
- Increase string similarity threshold from 0.1 to 0.3 for more accurate matching
- Reduce frontend debounce from 5s to 1.5s and flush pending saves on unmount
- Fix series property updates (useCover, isStorage, useTitle) to persist to state
- Add GET /api/setup/job-status endpoint for wizard job status queries
- Resume scan/install/search progress after page refresh instead of restarting
- Restore original Kaizoku.NET naming throughout (API title, UI strings,
  wizard text, tray app, build scripts, README, unraid template)
- Restore original kaizoku.net.png and kaizoku.net.ico logo files
- Remove kaizoku-logo.png/ico replacements
- Revert repo URL changes back to Kaizoku.NET
- All functional code changes (bug fixes, features, mobile UI) preserved
Remove premature </div> that closed the space-y-4 wrapper too early,
leaving adjacent sibling JSX elements without a fragment wrapper.
This caused SWC to fail with "Unexpected token div" during next build.
Add useSettings, Checkbox, Label, MultiSelect imports.
Replace non-existent MultiSelectLanguages with MultiSelect.
Add availableLanguageOptions computed from extensions.
Wire filteredLanguages into availableExtensions filter.
@Quickkill0 Quickkill0 merged commit 222168a into main Feb 18, 2026
1 check failed
@Quickkill0 Quickkill0 deleted the fixes branch February 18, 2026 15:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant